﻿#include "plotgraphview.h"
#include "plotdata.h"
#include <QSharedPointer>
PlotGraphView::PlotGraphView(QSharedPointer< PlotModel> M, QWidget*parent)
	: QCustomPlot(parent),
	_plotModel(M)
{
	_p.plotLayout()->clear();
	_p.setMaximumSize(QSize(0, 0));
	RemoveQCPAxisRectAll();

	this->setInteractions(// QCP::iRangeDrag | QCP::iRangeZoom);
		QCP::iSelectPlottables |
		QCP::iSelectAxes |
		QCP::iSelectLegend |
		QCP::iSelectItems |
		QCP::iMultiSelect |
		QCP::iRangeDrag |
		QCP::iRangeZoom	
	);
	connect(&_timer, &QTimer::timeout, this, [&]() {
	if(this->isVisible())	this->replot(QCustomPlot::rpQueuedReplot);
		});
	_timer.start(40);
	_updateTimer.start(20);
	setShowModel(OneYAxis);
	connect(&_updateTimer, &QTimer::timeout, this, [&]() {_updateTimerEn = true; });
	connect(this, &PlotGraphView::pShowModelChanged, this, &PlotGraphView::_ShowModel);	
	InitUI();
}

PlotGraphView::~PlotGraphView()
{

}
void PlotGraphView::InitUI()
{
	_axisRect = static_cast<QCPAxisRect*> (this->plotLayout()->elementAt(0));
	this->plotLayout()->setColumnSpacing(0);
	this->plotLayout()->setRowSpacing(0);
	this->plotLayout()->setWrap(1);
	//this->plotLayout()->setColumnStretchFactors(0, 0, _axisRect);//比列


}
void PlotGraphView::Initconnect()
{

}
/**
* 在此函数中添加数据
*/
void PlotGraphView::chekStatusChanged_Slot(QSharedPointer<PlotData>& /* _plotdata*/)
{
	auto data = _plotModel->rootItems()->current();
	
	if ( data.isNull()) return;
	bool bSet = data->getcheckStatus();

	if (data->getcheckStatus())//显示曲线
	{
		if (getShowModel() != MoreMore) {
			data->_oneRect_axisRect = _axisRect;
			data->axisRect = _axisRect;
		}
		data->InitPlotData(this);

		_changeAxis(data);
		_connectAllxAsix(false); 
		_connectAllxAsix(true);
	}
	else {//隐藏
		data->setHide();

	}

}

void PlotGraphView::RemoveQCPAxisRectAll()
{
	this->plotLayout()->clear();

	this->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
	
	_axisRect = new QCPAxisRect(this,false);
	QCPMarginGroup* marginGroup = new QCPMarginGroup(this);
	_axisRect->setMarginGroup(QCP::msLeft, marginGroup);
	_axisRect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight);
	_axisRect->setRangeDrag(Qt::Horizontal | Qt::Vertical); //水平方向拖动
	_axisRect->setRangeZoom(Qt::Horizontal | Qt::Vertical); //水平方向缩放
	_axisRect->setMargins(QMargins(0, 0, 0, 20));
	auto xAxis = _axisRect->addAxes(QCPAxis::atBottom);
	xAxis[0]->grid()->setVisible(true);
	xAxis[0]->grid()->setSubGridVisible(false);
	this->plotLayout()->addElement(0, 0, _axisRect);
	this->plotLayout()->simplify();
	this->plotLayout()->updateLayout();
	this->plotLayout()->simplify();	
}

void PlotGraphView::mousePressEvent(QMouseEvent* event)
{
	_isPressed = true;
	QCustomPlot::mousePressEvent(event);
	QVariant info;
	auto obj = layerableAt(event->pos(), true, &info);//查找特定像素位置处的顶层可图层对象（QCPLayerable）的函数
	if (!obj) return;
	// 获取鼠标点击位置的轴
	if(info.canConvert< QCPAxis::SelectablePart>())//		// 找到了一个轴，可以进行进一步处理
	{
		auto axis = qobject_cast<QCPAxis*>(obj);
		setCursor(Qt::ClosedHandCursor);//设置鼠标形状
		if (axis->orientation() == Qt::Vertical) {
			//this->xAxis, setVisible(false);
			for (auto const& var : _plotModel->rootItems()->data()) {
				if (!var.isNull()) {
					if (var->yAxis == axis) {
						emit changedPlotData(var);
						_connectAllxAsix(false);
					}
				}
			}
		}

	}
	else if((info.canConvert<QCPDataSelection>()) )// 找到了一个曲线，可以进行进一步处理
	{		
		auto graph = qobject_cast<QCPGraph*>(obj);
		//	qDebug() << "Clicked on graph:" << graph->dataCount();
		setCursor(Qt::ClosedHandCursor);
			for (auto const& var : _plotModel->rootItems()->data()) {
				if (!var.isNull()) {
					if (var->_graph == graph) {
						
						emit changedPlotData(var);
						_connectAllxAsix(false);
					}
				}
			}
		
	}
	else if (qobject_cast<QCPItemStraightLine*>(obj)) {
		setCursor(Qt::ClosedHandCursor);
		//if (obj == _LefLine.get()) {
			_LefLineMoveEn = true;
		//}
	}
	else {
		qDebug() << "Clicked on something else:" << info;
	}
	
}

void PlotGraphView::mouseReleaseEvent(QMouseEvent* event)
{

	QCustomPlot::mouseReleaseEvent(event);
	_connectAllxAsix(false);_connectAllxAsix(true);
	_isPressed = false;
	_LefLineMoveEn = false;
	mouseMoveEvent(event); //刷新鼠标图标

}

void PlotGraphView::mouseMoveEvent(QMouseEvent* event)
{
	if (_moveLine(event)) return;
	QCustomPlot::mouseMoveEvent(event);
	if (_isPressed)return;
	if (_updateTimerEn) {
		QVariant info;
		auto obj = layerableAt(event->pos(), true, &info);
		if (!obj) {
			setCursor(Qt::ArrowCursor);
			return;
		}
		// 获取鼠标点击位置的轴
		if (info.canConvert< QCPAxis::SelectablePart>())//		// 找到了一个轴，可以进行进一步处理
		{
			auto axis = qobject_cast<QCPAxis*>(obj);
			setCursor(Qt::OpenHandCursor);
		}
		else if ((info.canConvert<QCPDataSelection>())) {//		// 找到了一个曲线，可以进行进一步处理

			auto graph = qobject_cast<QCPGraph*>(obj);
			setCursor(Qt::OpenHandCursor);
			//qDebug() << "Clicked on graph:" << graph->dataCount();
		}
		else if (qobject_cast<QCPItemStraightLine*>(obj)) {
			setCursor(Qt::OpenHandCursor);
		}
		else {
			setCursor(Qt::ArrowCursor);
		}	
	}
	_updateTimerEn = false;
}

void PlotGraphView::contextMenuEvent(QContextMenuEvent* event)
{
	// 创建一个菜单
	QMenu menu(this);
	// 添加菜单项
	QAction* autoAction = menu.addAction(QString("自适应"));
	QAction* saveAction = menu.addAction("Save");
	QAction* exitAction = menu.addAction("Exit");

	// 显示菜单，并获取用户选择的菜单项
	QAction* selectedAction = menu.exec(event->globalPos());

	// 根据用户选择的菜单项执行相应的操作
	if (selectedAction == autoAction) {
		for (auto i = 0; i < this->graphCount(); i++) {
			this->graph(i)->rescaleAxes();
		}
	}
	else if (selectedAction == saveAction) {
		// 执行保存操作
	}
	else if (selectedAction == exitAction) {
		// 执行退出操作
		QApplication::quit();
	}
}

void PlotGraphView::wheelEvent(QWheelEvent* event)
{
	QVariant info;
	auto obj = layerableAt(event->position().toPoint(), true, &info);//查找特定像素位置处的顶层可图层对象（QCPLayerable）的函数
	// 获取鼠标点击位置的轴
	if (info.canConvert< QCPAxis::SelectablePart>() && obj)//找到了一个轴，可以进行进一步处理
	{
		auto axis = qobject_cast<QCPAxis*>(obj);
		if (axis->orientation() == Qt::Vertical) {
			const QSharedPointer<PlotData>& plot_data(_plotModel->rootItems()->getPlotData(axis));
			if (!plot_data.isNull()) {
				emit changedPlotData(plot_data);
			}
		}
	}

	QCustomPlot::wheelEvent(event);
}

void simulateMouseReleaseEvent(QWidget* widget, const QPoint& pos) {
	// 创建一个鼠标释放事件
	QMouseEvent releaseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
	// 将事件发送给widget
	QApplication::postEvent(widget, new QMouseEvent(releaseEvent));
}
void PlotGraphView::_changeAxis(QSharedPointer< PlotData> & data)
{
	if (_currentPlotData->getdata_ptr() != data->getdata_ptr()) {
		
		_currentPlotData = data;
	}
	if (_LefLine.isNull()) {
		QPen pen(Qt::blue, 1, Qt::SolidLine); //颜色 、宽度、样式（直线）
		_LefLine =new QCPItemStraightLine(this);
		_LefLine->setLayer("overlay");
		_LefLine->setPen(pen);//设置游标线的样式
		_LefLine->setClipToAxisRect(true);//自适应范围
		_LefLine->point1->setCoords(2, 0);//起点坐标
		_LefLine->point2->setCoords(2, 5);//终点坐标
		_LefLine->setVisible(true);//默认隐藏
	}
}

/// <summary>
/// NOTE:修改显示模式
/// </summary>
void PlotGraphView::_ShowModel()
{

	QCPAxis* axis_ptr = nullptr;
	bool flag = false;
	int index = 0;
	_axisRect->setVisible(true);
	if (!this->plotLayout()->hasElement(0, 0))
	{
		this->plotLayout()->addElement(0, 0, _axisRect);
	}
	switch (getShowModel())
	{
	default:
		setShowModel(OneYAxis);
		_ShowModel();
		for (auto& var : _plotModel->rootItems()->data()) {
			var->axisRect = _axisRect;
			var->InitPlotData(this);
			var->axisRect->setVisible(true);
		}
		break;
	case OneYAxis://单Y轴
		if(_currentPlotData.isNull())return;
		for (auto& var : _plotModel->rootItems()->data()) {
			var->axisRect = _axisRect;
			var->InitPlotData(this);
		}
		for (auto& axis : _currentPlotData->axisRect->axes(QCPAxis::atLeft)) {
			if (_plotModel->rootItems()->getChekStatus(axis)) {
				axis_ptr = axis;
				if (axis == _currentPlotData->yAxis)
				{
					axis->setVisible(true);
					flag = true;
					continue;
				}
			}
			axis->setVisible(false);
		}
		if (!flag && axis_ptr) {
			emit changedPlotData(_plotModel->rootItems()->getPlotData(axis_ptr));
		}

		break;
	case MoreYAxis:
		if (_currentPlotData.isNull())return;
		for (auto& var : _plotModel->rootItems()->data()) {
			var->axisRect = _axisRect;
			var->InitPlotData(this);
		}
		for (auto& axis : _currentPlotData->axisRect->axes(QCPAxis::atLeft)) {
			axis->setVisible(true && _plotModel->rootItems()->getChekStatus(axis));
		}

		break;
	case MoreMore:
		 this->plotLayout()->take(_axisRect);

		_axisRect->setVisible(false);
		for (auto& var :_plotModel->rootItems()->data()) {
			var->axisRect = var->_moreRect_axisRect;

			var->InitPlotData(this);
			this->plotLayout()->addElement(var->axisRect);
			
			index++;
			for (auto& chid : _plotModel->rootItems()->data()) {
				if (chid->xAxis != var->xAxis) {
					connect(var->xAxis,QOverload<const QCPRange & >::of( & QCPAxis::rangeChanged), chid->xAxis, QOverload<const QCPRange& >::of ( & QCPAxis::setRange));
				}
			}
		}
		
		break;
	}
	this->plotLayout()->simplify();  
	this->plotLayout()->update(QCPLayout::upLayout);

}
void PlotGraphView::_connectAllxAsix(bool on)
{
	if(_plotModel.isNull())return;
	if(getShowModel() != OneYAxis)on = false;//单Y轴才连接
	auto m = _plotModel->rootItems()->data();
	//auto m = _dataList.toList();

	for (int i = 0; i < m.count(); ++i) {
		if(m[i]->yAxis == nullptr)continue;

		for (int j = 0; j < m.count(); ++j) {
			if(m[j]->yAxis == nullptr)continue;
			if(m[i]->yAxis == m[j]->yAxis)continue;
			if (on)
			{
				connect(m[i]->yAxis, QOverload<const QCPRange&>::of(& QCPAxis::rangeChanged), m[j]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
				connect(m[j]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged), m[i]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
				
			}
			else
			{
				disconnect(m[i]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged), m[j]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
				disconnect(m[j]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged), m[i]->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
			}

		}
	}
}
/// <summary>
/// 游标线移动
/// </summary>
/// <param name="event"></param>
/// <returns></returns>
bool PlotGraphView::_moveLine(QMouseEvent* event)
{
	if(_currentPlotData.isNull())return false;
	try {
		//当前鼠标位置（像素坐标）
		double x_pos = event->pos().x();
		double y_pos = event->pos().y();

		//像素坐标转成实际的x,y轴的坐标
		double x_val = _currentPlotData->xAxis->pixelToCoord(x_pos);
		double y_val = _currentPlotData->yAxis->pixelToCoord(y_pos);
		//qDebug()<<"x_val:"<<x_val<<"y_val:"<<y_val;
		//获取当前曲线上最近的X轴点坐标
		//auto iter = _currentPlotData->_data->findEnd(x_val);
		//x_val = iter->mainKey();

		//获取当前游标X轴的坐标
		double r_point = _LefLine->point1->key();
		//获取距离
		double distanceLV = _LefLine->selectTest(event->pos(), false);
		//当鼠标在游标上时改变鼠标形状

		//游标移动判断
		if (_LefLineMoveEn)
		{//移动左游标
			_LefLine->point1->setCoords(x_val, _currentPlotData->yAxis->range().lower);
			_LefLine->point2->setCoords(x_val, _currentPlotData->yAxis->range().upper);
			_setTracer(x_val);
			return true;
		}
	}
	catch (...) {
		qDebug()<<"系统发异常！";
		
	}
	return false;
}

bool PlotGraphView::_setTracer(double x)
{
	try {
		_currentPlotData->setTracer(x);
		return true;
	}
	catch (...) {
		qCritical() << "_setTracer Err";
		return false;
	}
}
